// (C) Copyright 2012 Kystar. All rights reserved.

`timescale 1ns/100ps

module rgb2yuv 
(
    input  I_pclk,
    input  I_vsync,
    input  I_hsync,
    input  I_de,
    input  [ 23: 0] I_data,
    output reg O_vsync,
    output reg O_hsync,
    output reg O_de,
    output reg [ 23: 0] O_data,
    input  I_enable
);

/******************************************************************************
                                <localparams>
******************************************************************************/

/******************************************************************************
                              <internal signals>
******************************************************************************/
reg  vsync_in, hsync_in, de_in;
reg  [ 7: 0] R, G, B;
reg  vsync_x1, hsync_x1, de_x1;
reg  vsync_x2, hsync_x2, de_x2;
reg  [ 23: 0] data_x1,data_x2;
reg  [ 10: 0] Y_x2, U_x2, V_x2;
reg  [ 10: 0] Y_x1_1, U_x1_1, V_x1_1;
reg  [ 10: 0] Y_x1_2, U_x1_2, V_x1_2;
wire [ 7: 0] Y, U, V;

/******************************************************************************
                                <module body>
******************************************************************************/
always @(posedge I_pclk)
    begin
    R <= I_data[23:16];
    G <= I_data[15:8];
    B <= I_data[7:0];
    vsync_in <= I_vsync;
    hsync_in <= I_hsync;
    de_in <= I_de;
    end

always @(posedge I_pclk)
    begin
    vsync_x1 <= vsync_in;
    hsync_x1 <= hsync_in;
    de_x1 <= de_in;
    data_x1 <= {R,G,B};
    Y_x1_1 <= R + {G,1'b0};
    Y_x1_2 <= B + 2;
    U_x1_1 <= 128 * 4 + {B,1'b0} + 2;
    U_x1_2 <= R + G;
    V_x1_1 <= 128 * 4 + {R,1'b0} + 2;
    V_x1_2 <= G + B;
    end

always @(posedge I_pclk)
    begin
    vsync_x2 <= vsync_in;
    hsync_x2 <= hsync_in;
    de_x2 <= de_in;
    data_x2 <= {R,G,B};
    Y_x2 <= Y_x1_1 + Y_x1_2;
    U_x2 <= U_x1_1 - U_x1_2; 
    V_x2 <= V_x1_1 - V_x1_2;
    end

assign Y = Y_x2[10] ? 255 : Y_x2[9:2];
assign U = U_x2[10] ? 255 : U_x2[9:2];
assign V = V_x2[10] ? 255 : V_x2[9:2];

always @(posedge I_pclk)
    begin
    O_data <= I_enable ? {Y, U, V} : data_x2;
    O_vsync <= vsync_x2;
    O_hsync <= hsync_x2;
    O_de <= de_x2;
    end

endmodule

